<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/8/9
 * Time: 14:22
 */

namespace app\index\controller;
use       think\Db;
use       think\Cache;
//调用封装的微信接口
vendor('api.weixinapi');
class Wxcommon
{
    //验证签名
    public function valid()
    {
        $echoStr   = $_GET["echostr"];
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce     = $_GET["nonce"];
        $token     = "weixin";
        $tmpArr    = array($token, $timestamp, $nonce);
        //排序
        sort($tmpArr, SORT_STRING);
        //拼接
        $tmpStr = implode($tmpArr);
        //加密
        $tmpStr = sha1($tmpStr);
        //验证成功
        if($tmpStr == $signature){
            echo $echoStr;
            exit;
        }
    }
    //响应消息
    public function responseMsg()
    {
        //微信公共号发过来的xml 转换成对象
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        if (!empty($postStr)){
            $this->logger("R \r\n".$postStr);   // 写入日志文件
            //微信公共号发过来的xml 转换成对象
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $RX_TYPE = trim($postObj->MsgType); // 信息分类

            //消息类型分离
            switch ($RX_TYPE)
            {
                //事件相应函数
                case "event":
                    $result = $this->receiveEvent($postObj);
                    break;
                //文本相应函数
                case "text":
                    $result = $this->receiveText($postObj);
                    break;
                //图片相应函数
                case "image":
                    $result = $this->receiveImage($postObj);
                    break;
                //方位相应函数
                case "location":
                    $result = $this->receiveLocation($postObj);
                    break;
                //声音相应函数
                case "voice":
                    $result = $this->receiveVoice($postObj);
                    break;
                //视频相应函数
                case "video":
                case "shortvideo":
                    $result = $this->receiveVideo($postObj);
                    break;
                //链接相应函数
                case "link":
                    $result = $this->receiveLink($postObj);
                    break;
                default:
                    $result = "unknown msg type: ".$RX_TYPE;
                    break;
            }
            //写入日志文件和输入信息
            $this->logger("T \r\n".$result);
            echo $result;
        }else {
            echo "没有相关操作";
            exit;
        }
    }

    //接收事件消息
    private function receiveEvent($object)
    {
        $content = "";
        switch ($object->Event)
        {
            case "subscribe": //开始关注发送信息
                $content=array();
                //$data=Db::table('x_textpic')->where('type',1)->find();
                $name=$this->getMessageByOpenId($object);
                // $content[]=array("Title"=>$data['title'].$name,"Description"=>$data['description'],"PicUrl"=>"http://mg.bonayiyou.com/uploads/20170914\e668b17ba221f0fe024b67ff37236276.jpg","Url"=>$data['url']);
                $content[]=array("Title"=>"欢迎关注福乐家家庭一站式教育平台","Description"=>"","PicUrl"=>"http://mg.bonayiyou.com/uploads/20170914/e668b17ba221f0fe024b67ff37236276.jpg","Url"=>"http://mg.bonayiyou.com/index/home/home.html");
                break;
            case "unsubscribe"://取消关注的时候
                $content = "取消关注";
                break;
            case "CLICK":     //点击事件
                switch ($object->EventKey)
                {
                    case "zhan1":
                        $content=array();
                        //相应点击事件发送图文消息
                        $content[]=array("Title"=>"精选案例","Description"=>"展览展示案例精选","PicUrl"=>"http://www.yaotianzl.com/uploads/allimg/160720/1-160H0142F70-L.jpg","Url"=>"http://www.yaotianzl.com/uploads/1.html");
                        break;
                    case "zhan2":
                        $content=array();
                        $content[]=array("Title"=>"精选案例","Description"=>"舞台活动策划案例精选","PicUrl"=>"http://www.yaotianzl.com/uploads/allimg/150727/1-150HG63P10-L.jpg","Url"=>"http://www.yaotianzl.com/uploads/2.html");
                        break;
                    case "zhan3":
                        $content=array();
                        $content[]=array("Title"=>"精选案例","Description"=>"展厅/博物馆案例精选","PicUrl"=>"http://www.yaotianzl.com/uploads/allimg/160909/1-160Z91509360-L.jpg", "Url" =>"http://www.yaotianzl.com/uploads/3.html");
                        break;
                    case "zhan4":
                        $content=array();
                        $content[] = array("Title"=>"我们领风前行我们不断超越",  "Description"=>"023-62624374 \n
                                                                                                 (周一~周五 9：00~19：00)\n
                                                                                                 023-62624374(聂) 13668080448(聂)  
                                                                                                 QQ咨询: 741843179  \n 
                                                                                                 地址：重庆市南岸区铜元局亚太商谷5栋23-3\n
                                                                                                 乘车路线：乘坐地铁3号线。
点击查看地图详情", "PicUrl"=>"http://www.yaotianzl.com/dede58/images/contact.jpg", "Url" =>"http://www.yaotianzl.com/uploads/ditu.html");
                        break;
                    case "zhan5":
                        $content=array();
                        $content[]=array("Title"=>"官方微信","Description"=>"欢迎加入官方微信 官网地址:www.yaotianzl.com","PicUrl"=>"http://1.weixinnie.applinzi.com/img/qrcode_for_gh_00373fb41efc_430.jpg");
                        break;
                    default:
                        $content="没有相关命令";
                        break;

                }
                break;
            case "VIEW":
                $content = "跳转链接 ".$object->EventKey;
                break;
            case "SCAN":
                $content = "扫描场景 ".$object->EventKey;
                break;
            case "LOCATION":
                $content = "上传位置：纬度 ".$object->Latitude.";经度 ".$object->Longitude;
                break;
            case "scancode_waitmsg":
                if ($object->ScanCodeInfo->ScanType == "qrcode"){
                    $content = "扫码带提示：类型 二维码 结果：".$object->ScanCodeInfo->ScanResult;
                }else if ($object->ScanCodeInfo->ScanType == "barcode"){
                    $codeinfo = explode(",",strval($object->ScanCodeInfo->ScanResult));
                    $codeValue = $codeinfo[1];
                    $content = "扫码带提示：类型 条形码 结果：".$codeValue;
                }else{
                    $content = "扫码带提示：类型 ".$object->ScanCodeInfo->ScanType." 结果：".$object->ScanCodeInfo->ScanResult;
                }
                break;
            case "scancode_push":
                $content = "扫码推事件";
                break;
            case "pic_sysphoto":
                $content = "系统拍照";
                break;
            case "pic_weixin":
                $content = "相册发图：数量 ".$object->SendPicsInfo->Count;
                break;
            case "pic_photo_or_album":
                $content = "拍照或者相册：数量 ".$object->SendPicsInfo->Count;
                break;
            case "location_select":
                $content = "发送位置：标签 ".$object->SendLocationInfo->Label;
                break;
            default:
                $content = "receive a new event: ".$object->Event;
                break;
        }

        if(is_array($content)){
            $result = $this->transmitNews($object, $content); // 把php中的对象文件转换成 xml  微信平台的信息格式
        }else{
            $result = $this->transmitText($object, $content);
        }
        return $result;
    }

    //接收文本消息
    private function receiveText($object)
    {
        $keyword = trim($object->Content);
        //多客服人工回复模式
        if (strstr($keyword, "请问在吗") || strstr($keyword, "在线客服")){
            $result = $this->transmitService($object);
            return $result;
        }
        else

        {
            $content=array();
            //$data=Db::table('x_textpic')->where('type',1)->find();
            // $content[]=array("Title"=>$data['title'],"Description"=>$data['description'],"PicUrl"=>"http://mg.bonayiyou.com/uploads/20170914\e668b17ba221f0fe024b67ff37236276.jpg","Url"=>$data['url']);
            $content[]=array("Title"=>"欢迎关注福乐家家庭一站式教育平台","Description"=>"","PicUrl"=>"http://mg.bonayiyou.com/uploads/20170914/e668b17ba221f0fe024b67ff37236276.jpg","Url"=>"http://mg.bonayiyou.com/index/home/home.html");
            
        }

        if(is_array($content)){
            if (isset($content[0])){
                $result = $this->transmitNews($object, $content);
            }else if (isset($content['MusicUrl'])){
                $result = $this->transmitMusic($object, $content);
            }
        }else{
            $result = $this->transmitText($object, $content);
        }
        return $result;
    }

    //接收图片消息
    private function receiveImage($object)
    {
        $content = array("MediaId"=>$object->MediaId);
        $result = $this->transmitImage($object, $content);
        return $result;
    }

    //接收位置消息
    private function receiveLocation($object)
    {
        $content = "你发送的是位置，经度为：".$object->Location_Y."；纬度为：".$object->Location_X."；缩放级别为：".$object->Scale."；位置为：".$object->Label;
        $result = $this->transmitText($object, $content);
        return $result;
    }

    //接收语音消息
    private function receiveVoice($object)
    {
        if (isset($object->Recognition) && !empty($object->Recognition)){
            $content = "你刚才说的是：".$object->Recognition;
            $result = $this->transmitText($object, $content);
        }else{
            $content = array("MediaId"=>$object->MediaId);
            $result = $this->transmitVoice($object, $content);
        }
        return $result;
    }

    //接收视频消息
    private function receiveVideo($object)
    {
        $content = "上传视频类型：".$object->MsgType;
        $result = $this->transmitText($object, $content);
        return $result;
    }

    //接收链接消息
    private function receiveLink($object)
    {
        $content = "你发送的是链接，标题为：".$object->Title."；内容为：".$object->Description."；链接地址为：".$object->Url;
        $result = $this->transmitText($object, $content);
        return $result;
    }

    //回复文本消息
    private function transmitText($object, $content)
    {
        if (!isset($content) || empty($content)){
            return "没有这类文本信息";
        }
        //文本信息

        $xmlTpl = "<xml>
        <ToUserName><![CDATA[%s]]></ToUserName>
        <FromUserName><![CDATA[%s]]></FromUserName>
        <CreateTime>%s</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[%s]]></Content>
        </xml>";
        $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), $content);

        return $result;
    }

    //回复图文消息
    private function transmitNews($object, $newsArray)
    {
        if(!is_array($newsArray)){
            return "";
        }
        $itemTpl = "        <item>
            <Title><![CDATA[%s]]></Title>
            <Description><![CDATA[%s]]></Description>
            <PicUrl><![CDATA[%s]]></PicUrl>
            <Url><![CDATA[%s]]></Url>
        </item>
";
        $item_str = "";
        foreach ($newsArray as $item){
            $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
        }
        $xmlTpl = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[news]]></MsgType>
    <ArticleCount>%s</ArticleCount>
    <Articles>
$item_str    </Articles>
</xml>";

        $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), count($newsArray));
        return $result;
    }

    //回复音乐消息
    private function transmitMusic($object, $musicArray)
    {
        if(!is_array($musicArray)){
            return "";
        }
        $itemTpl = "<Music>
        <Title><![CDATA[%s]]></Title>
        <Description><![CDATA[%s]]></Description>
        <MusicUrl><![CDATA[%s]]></MusicUrl>
        <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
    </Music>";

        $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);

        $xmlTpl = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[music]]></MsgType>
    $item_str
</xml>";

        $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }

    //回复图片消息
    private function transmitImage($object, $imageArray)
    {
        $itemTpl = "<Image>
        <MediaId><![CDATA[%s]]></MediaId>
    </Image>";

        $item_str = sprintf($itemTpl, $imageArray['MediaId']);

        $xmlTpl = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[image]]></MsgType>
    $item_str
</xml>";

        $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }

    //回复语音消息
    private function transmitVoice($object, $voiceArray)
    {
        $itemTpl = "<Voice>
        <MediaId><![CDATA[%s]]></MediaId>
    </Voice>";

        $item_str = sprintf($itemTpl, $voiceArray['MediaId']);
        $xmlTpl = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[voice]]></MsgType>
    $item_str
</xml>";

        $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }

    //回复视频消息
    private function transmitVideo($object, $videoArray)
    {
        $itemTpl = "<Video>
        <MediaId><![CDATA[%s]]></MediaId>
        <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
        <Title><![CDATA[%s]]></Title>
        <Description><![CDATA[%s]]></Description>
    </Video>";

        $item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);

        $xmlTpl = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[video]]></MsgType>
    $item_str
</xml>";

        $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }

    //回复多客服消息
    private function transmitService($object)
    {
        $xmlTpl = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[transfer_customer_service]]></MsgType>
</xml>";
        $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }

    //回复第三方接口消息
    private function relayPart3($url, $rawData)
    {
        $headers = array("Content-Type: text/xml; charset=utf-8");
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $rawData);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }

    //字节转Emoji表情
    function bytes_to_emoji($cp)
    {
        if ($cp > 0x10000){       # 4 bytes
            return chr(0xF0 | (($cp & 0x1C0000) >> 18)).chr(0x80 | (($cp & 0x3F000) >> 12)).chr(0x80 | (($cp & 0xFC0) >> 6)).chr(0x80 | ($cp & 0x3F));
        }else if ($cp > 0x800){   # 3 bytes
            return chr(0xE0 | (($cp & 0xF000) >> 12)).chr(0x80 | (($cp & 0xFC0) >> 6)).chr(0x80 | ($cp & 0x3F));
        }else if ($cp > 0x80){    # 2 bytes
            return chr(0xC0 | (($cp & 0x7C0) >> 6)).chr(0x80 | ($cp & 0x3F));
        }else{                    # 1 byte
            return chr($cp);
        }
    }

    //日志记录
    private function logger($log_content)
    {
        file_put_contents('log.xml',$log_content,FILE_APPEND);
    }

    //根据用户的openID 获取信息然后存入数据库中
    public function getMessageByOpenId($object)
    {
        $result=$this->get_weixinUserByOpenid($object->FromUserName);

        //获取微信用户的信息存入数据库中
        $data=array(
            'subscribe'=>$result->subscribe,
            'openid'  =>$result->openid,
            'nickname'=>$result->nickname,
            'sex'     =>$result->sex,
            'language'=>$result->language,
            'city'    =>$result->city,
            'province'=>$result->province,
            'headimgurl'=>$result->headimgurl,
            'subscrbe_time'=>date('Y-m-d'),
        );
        Db::table('x_weixin_user')->insert($data);
        return $result->nickname;
    }

    //启用curl 模仿游览器使用https协议访问链接
    private function http_url($url,$data=null)
    {
        //1.初始化，创建一个新cURL资源
        $ch = curl_init();
        //2.设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //curl_setopt($ch, CURLOPT_HEADER, 0);
        if(!empty($data)){
            curl_setopt($ch,CURLOPT_POST,1);
            curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
        }
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//不检测服务器的证书是否由正规浏览器认证过的授权CA颁发
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//不检测服务器的域名与证书上的是否一致
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//禁止curl资源直接输出
        //3.抓取URL并把它传递给浏览器
        $opt=curl_exec($ch);
        //4.关闭cURL资源，并且释放系统资源
        curl_close($ch);
        return $opt;
    }
     //获取access_toen
     public function getAccess_token()
    {
        $appid="wxcd4dce13c9fb1a0a";   //微信公众号唯一标识
        $secret="a9f3c9753b70b42573fdd6440090c1c6";  //秘钥
        $url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}";
        $json=$this->http_url($url);
        $result=json_decode($json);
        //写入自己定义的缓存文件
        $data=array();
        $data['access_token']=$result->access_token;
        $data['time_out']=time();
        $string=json_encode($data);
        file_put_contents('token.txt',$string);
        return $result->access_token;
    }
    //获取用户基本信息
    public function get_weixinUserByOpenid($openId)
    {
        //判断access_token缓存是否过期
        if(jugement_token_value())
        {
        $access_token=get_access_token_ache();
        }
        else{
        $access_token=$this->getAccess_token();
        }   
        $url  ="https://api.weixin.qq.com/cgi-bin/user/info?access_token={$access_token}&openid={$openId}&lang=zh_CN";
        $result=$this->http_url($url);
        return json_decode($result);  //json字符串转换成json数组
    }
}